package com.ninong.ker.admin.service.impl;

import java.util.Arrays;
import java.util.List;

import cn.hutool.crypto.SecureUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.ninong.ker.admin.service.UserService;
import com.ninong.ker.common.auth.SecurityAdmin;
import com.ninong.ker.common.user.OnlineUser;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.ObjectUtils;
import org.springframework.util.StringUtils;

import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.ninong.ker.admin.domain.Dept;
import com.ninong.ker.admin.domain.User;
import com.ninong.ker.admin.domain.UserRole;
import com.ninong.ker.admin.mapper.DeptMapper;
import com.ninong.ker.admin.mapper.UserMapper;
import com.ninong.ker.admin.mapper.UserRoleMapper;
import com.ninong.ker.admin.service.dto.UserDTO;
import com.ninong.ker.common.exception.CmdException;
import com.ninong.ker.common.tools.Constants;
import com.ninong.ker.common.tools.enums.BusinessEnum;

import cn.hutool.core.lang.UUID;

/**
 * @author cmd
 */
@Service
@Transactional(rollbackFor = RuntimeException.class)
public class UserServiceImpl extends ServiceImpl<UserMapper, User> implements UserService {

    private static final String PASSWORD = "cmd.c0m";
    private static final String PARENT = "0";

    @Autowired
    private DeptMapper deptMapper;
    @Autowired
    private UserRoleMapper userRoleMapper;
    @Autowired
    private SecurityAdmin securityAdmin;

    @Override
    public PageInfo<User> listPage(UserDTO dto) {
        PageHelper.startPage(dto.getCurrentPage(), dto.getPageSize());
        OnlineUser onlineUser = securityAdmin.currentUser();
        dto.setTenantId(onlineUser.getTenantId());
        List<User> users = baseMapper.selectUserPage(dto);
        return new PageInfo<User>(users);
    }

    @Override
    public void delete(String[] ids) {
        List<String> idList = Arrays.asList(ids);
        idList.forEach(id -> {
            Integer count = userRoleMapper.selectCount(new LambdaQueryWrapper<UserRole>().eq(UserRole::getUserId, id));
            if (count > Constants.ZERO) {
                throw new CmdException(BusinessEnum.USER_ROLE_EXIST);
            }
            User entity = new User();
            entity.setId(id);
            entity.setDeleted(false);
            baseMapper.updateById(entity);
        });
    }

    @Override
    public void create(User entity) throws Exception {
        if (StringUtils.isEmpty(entity.getId())) {
            String salt = UUID.fastUUID().toString();
            entity.setSalt(salt);
            String password = SecureUtil.md5(salt + PASSWORD);
            entity.setPassword(password);
        }
        Integer count = null;
        if (StringUtils.isEmpty(entity.getId())) {
            count = baseMapper.selectCount(new LambdaQueryWrapper<User>().eq(User::getPhone, entity.getPhone()));
            if (count > Constants.ZERO) {
                throw new CmdException(BusinessEnum.USER_PHONE_REPEAT);
            }
            count = baseMapper.selectCount(new LambdaQueryWrapper<User>().eq(User::getEmail, entity.getEmail()));
            if (count > Constants.ZERO) {
                throw new CmdException(BusinessEnum.USER_EMAIL_REPEAT);
            }
        } else {
            count = baseMapper
                    .selectCount(new LambdaQueryWrapper<User>().ne(User::getId, entity.getId()).eq(User::getPhone, entity.getPhone()));
            if (count > Constants.ZERO) {
                throw new CmdException(BusinessEnum.USER_PHONE_REPEAT);
            }
            count = baseMapper
                    .selectCount(new LambdaQueryWrapper<User>().ne(User::getId, entity.getId()).eq(User::getEmail, entity.getEmail()));
            if (count > Constants.ZERO) {
                throw new CmdException(BusinessEnum.USER_EMAIL_REPEAT);
            }

        }
        saveOrUpdate(entity);
    }

    @Override
    public User get(String id) {
        User entity = baseMapper.selectById(id);
        if (ObjectUtils.isEmpty(entity)) {
            entity = new User();
        }
        Dept dto = new Dept();
        dto.setPid(PARENT);
        entity.setResouces(deptMapper.selectDeptTree(dto));
        return entity;
    }

    @Override
    public void enableUser(String id, Boolean enable) {
        User entity = new User();
        entity.setId(id);
        entity.setEnabled(enable);
        baseMapper.updateById(entity);
    }

    @Override
    public List<User> listUserTree() {
        LambdaQueryWrapper<User> query = new LambdaQueryWrapper<>();
        query.eq(User::getDeleted, Constants.DEFAULT_YES);
        query.select(User::getId, User::getNickName);
        List<User> users = baseMapper.selectList(query);
        return users;
    }

}
